home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- #include "sw.h"
- #include "extern.h"
- #include "universe.h"
- #include "main.h"
- #include "ship.h"
- #include "stars.h"
- #include "resources.h"
- #include <Inventor/nodes/SoGroup.h>
- #include <Inventor/nodes/SoRotation.h>
- #include <Inventor/nodes/SoDirectionalLight.h>
- #include <Inventor/nodes/SoEnvironment.h>
- #include <Inventor/nodes/SoComplexity.h>
- #include <Inventor/nodes/SoSphere.h>
- #include <Inventor/nodes/SoCube.h>
- #include <Inventor/nodes/SoMaterial.h>
- #include <Inventor/nodes/SoDrawStyle.h>
- #include <Inventor/nodes/SoSwitch.h>
- #include <gl/gl.h>
-
- #define RADARSIDES 12
-
- SoSeparator* universe; // universe database
- SoPerspectiveCamera* camera; // ship's camera
- SoTranslation* position; // camera position
- SoSeparator* ships; // ships under here
-
- static float teamBasePos[NUMTEAMS][3] = {
- { -FIELDSIZE, -FIELDSIZE, FIELDSIZE },
- { FIELDSIZE, -FIELDSIZE, -FIELDSIZE },
- { -FIELDSIZE, FIELDSIZE, FIELDSIZE },
- { FIELDSIZE, FIELDSIZE, -FIELDSIZE } };
- static float baseRadar[RADARSIDES][2];
-
- #define FS (1.2 * FIELDSIZE)
- static float asteroidPos[MAXASTEROIDS][3] = {
- { 0.336242*FS, 0.488682*FS, 0.441743*FS},
- { -0.148313*FS, 0.309765*FS, -0.190327*FS},
- { 0.759522*FS, 0.369414*FS, -0.994095*FS},
- { 0.355943*FS, 0.50475*FS, 0.579178*FS},
- { 0.613972*FS, -0.544913*FS, 0.37368*FS},
- { -0.582548*FS, -0.533237*FS, 0.770545*FS},
- { -0.386152*FS, 0.735704*FS, 0.892255*FS},
- { -0.537149*FS, -0.155228*FS, -0.477868*FS},
- { -0.439326*FS, -0.762477*FS, 0.487417*FS},
- { 0.860059*FS, -0.92119*FS, 0.847345*FS},
- { -0.163824*FS, -0.246843*FS, 0.121367*FS},
- { -0.566678*FS, 0.200692*FS, 0.0515372*FS},
- { -0.875666*FS, -0.659752*FS, 0.315128*FS},
- { -0.13777*FS, 0.657194*FS, 0.558865*FS},
- { -0.961172*FS, 0.82217*FS, -0.00139434*FS},
- { -0.656373*FS, -0.570957*FS, 0.412901*FS},
- { -0.536116*FS, 0.957052*FS, 0.92711*FS},
- { -0.755732*FS, -0.405562*FS, -0.0520596*FS},
- { -0.143542*FS, 0.141403*FS, -0.181507*FS},
- { 0.572489*FS, 0.622042*FS, 0.352845*FS},
- { -0.0643383*FS, -0.0193419*FS, -0.474457*FS},
- { -0.742051*FS, -0.272766*FS, -0.469329*FS},
- { -0.331464*FS, -0.102372*FS, -0.220405*FS},
- { -0.102167*FS, -0.942594*FS, -0.837588*FS},
- { 0.0567852*FS, -0.0502296*FS, 0.940972*FS},
- { 0.625724*FS, -0.889111*FS, 0.211249*FS},
- { -0.83133*FS, -0.719854*FS, 0.69488*FS},
- { 0.57322*FS, -0.229432*FS, -0.219259*FS},
- { 0.858013*FS, -0.290109*FS, 0.544527*FS},
- { 0.672019*FS, 0.934613*FS, -0.675743*FS},
- { 0.895152*FS, 0.752686*FS, -0.729632*FS},
- { 0.977198*FS, -0.569804*FS, -0.0937383*FS},
- { 0.461306*FS, -0.996515*FS, 0.439359*FS},
- { 0.0497952*FS, -0.810878*FS, -0.281791*FS},
- { 0.251234*FS, 0.999152*FS, 0.465801*FS},
- { 0.0676605*FS, -0.935549*FS, 0.631452*FS} };
- #define BR BASERADIUS
- static float asteroidRad[MAXASTEROIDS] =
- { 2.65415*BR,
- 0.271357*BR,
- 1.0589*BR,
- 0.410823*BR,
- 0.915408*BR,
- 1.15367*BR,
- 0.105465*BR,
- 2.18785*BR,
- 1.50325*BR,
- 0.399032*BR,
- 0.271209*BR,
- 0.926577*BR,
- 1.67525*BR,
- 1.32417*BR,
- 0.618128*BR,
- 0.168644*BR,
- 0.809082*BR,
- 0.0168345*BR,
- 2.65415*BR,
- 0.271357*BR,
- 1.0589*BR,
- 0.410823*BR,
- 0.915408*BR,
- 1.15367*BR,
- 0.105465*BR,
- 2.18785*BR,
- 1.50325*BR,
- 0.399032*BR,
- 0.271209*BR,
- 0.926577*BR,
- 1.67525*BR,
- 1.32417*BR,
- 0.618128*BR,
- 0.168644*BR,
- 0.809082*BR,
- 0.0168345*BR };
-
- static float* asteroidMass;
- static int numAsteroids;
- static SoSwitch** asteroidSwitch;
- static float (*asteroidRadar)[RADARSIDES][2];
-
- enum { NotInSpace = 0, InSpace = 1,
- NotVisible = 0, Visible = 2,
- SwitchedOn = InSpace | Visible };
-
- static SoSwitch* flags[NUMTEAMS];
- static SoSeparator* flagGeom[NUMTEAMS];
- static SoTranslation* flagPos[NUMTEAMS];
- static SoRotation* flagRot;
- static int flagState[NUMTEAMS];
- static SbRotation flagSpin(SbVec3f(0.0, 0.0, 1.0),
- SbVec3f(0.05416, -0.02394, 0.8845));
-
- static SoSeparator* makeTeamBase(Team t)
- {
- SoSeparator* base = new SoSeparator;
- base->setGLRenderCaching(TRUE);
-
- SoDrawStyle* baseStyle = new SoDrawStyle;
- base->addChild(baseStyle);
- baseStyle->style = SoDrawStyle::LINES;
-
- SoMaterial* baseMat = new SoMaterial;
- base->addChild(baseMat);
- baseMat->ambientColor.setValue(teamColor(t, 0.3));
- baseMat->diffuseColor.setValue(teamColor(t, 1.0));
-
- SoComplexity* baseCmplx = new SoComplexity;
- base->addChild(baseCmplx);
- baseCmplx->value = 0.33;
-
- SoTranslation* basePos = new SoTranslation;
- base->addChild(basePos);
- basePos->translation.setValue(teamBasePos[t]);
-
- SoSphere* baseGeom = new SoSphere;
- base->addChild(baseGeom);
- baseGeom->radius = BASERADIUS;
-
- return base;
- }
-
- static void makeBaseRadar()
- {
- for (int i = 0; i < RADARSIDES; i++) {
- baseRadar[i][0] = BASERADIUS * cos(2.0 * M_PI * float(i) / RADARSIDES);
- baseRadar[i][1] = BASERADIUS * sin(2.0 * M_PI * float(i) / RADARSIDES);
- }
- }
-
- static SoSeparator* makeAsteroids()
- {
- SoSeparator* asteroids = new SoSeparator;
-
- SoMaterial* asteroidMat = new SoMaterial;
- asteroids->addChild(asteroidMat);
- asteroidMat->ambientColor.setValue(0.1, 0.1, 0.1);
- asteroidMat->diffuseColor.setValue(0.5, 0.5, 0.5);
-
- numAsteroids = MAXASTEROIDS;
- asteroidMass = new float[numAsteroids];
- asteroidSwitch = new SoSwitch* [numAsteroids];
- asteroidRadar = (float(*)[RADARSIDES][2])new float[numAsteroids*RADARSIDES*2];
- for (int i = 0; i < numAsteroids; i++) {
- asteroidMass[i] = asteroidRad[i] * asteroidRad[i] * asteroidRad[i];
-
- asteroidSwitch[i] = new SoSwitch;
- asteroids->addChild(asteroidSwitch[i]);
- asteroidSwitch[i]->whichChild = SO_SWITCH_NONE;
-
- // make two levels of complexity for asteroids
- SoSeparator* a = new SoSeparator;
- a->setGLRenderCaching(TRUE);
- asteroidSwitch[i]->addChild(a);
-
- SoComplexity* asteroidCmplx = new SoComplexity;
- a->addChild(asteroidCmplx);
- asteroidCmplx->value = 0.33;
-
- SoTranslation* aPos = new SoTranslation;
- a->addChild(aPos);
- aPos->translation.setValue(asteroidPos[i]);
-
- SoSphere* aGeom = new SoSphere;
- a->addChild(aGeom);
- aGeom->radius = asteroidRad[i];
-
- a = new SoSeparator;
- a->setGLRenderCaching(TRUE);
- asteroidSwitch[i]->addChild(a);
-
- asteroidCmplx = new SoComplexity;
- a->addChild(asteroidCmplx);
- asteroidCmplx->value = 0.1;
-
- a->addChild(aPos);
- a->addChild(aGeom);
-
- for (int j = 0; j < RADARSIDES; j++) {
- asteroidRadar[i][j][0] = asteroidRad[i] *
- cos(2.0 * M_PI * float(j) / RADARSIDES);
- asteroidRadar[i][j][1] = asteroidRad[i] *
- sin(2.0 * M_PI * float(j) / RADARSIDES);
- }
- }
-
- return asteroids;
- }
-
- static SoSwitch* makeTeamFlag(Team t, SoGroup* flagBasic)
- {
- flagState[int(t)] = NotInSpace | NotVisible;
-
- flags[int(t)] = new SoSwitch;
- flags[int(t)]->whichChild = SO_SWITCH_NONE;
- SoSeparator* flagSep = new SoSeparator;
- flags[int(t)]->addChild(flagSep);
- flagSep->addChild(flagPos[int(t)] = new SoTranslation);
-
- flagSep->addChild(flagGeom[int(t)] = new SoSeparator);
- flagGeom[int(t)]->ref();
- SoMaterial* flagMat = new SoMaterial;
- flagGeom[int(t)]->addChild(flagMat);
- flagMat->ambientColor.setValue(teamColor(t, 0.3));
- flagMat->diffuseColor.setValue(teamColor(t, 1.0));
- flagGeom[int(t)]->addChild(flagBasic);
-
- return flags[int(t)];
- }
-
- SoSeparator* makeUniverse()
- {
- universe = new SoSeparator;
- universe->ref();
-
- // keep camera isolated so hud is not transformed
- SoSeparator* space = new SoSeparator; // all space under here
- universe->addChild(space);
-
- // add ship's camera for view screen
- space->addChild(camera = new SoPerspectiveCamera);
-
- // add stars
- space->addChild(makeStars(NUMSTARS));
-
- // add some ambient light
- SoEnvironment* ambient = new SoEnvironment;
- space->addChild(ambient);
- ambient->ambientIntensity.setValue(0.4);
-
- // add a light source for the sun
- SoDirectionalLight *sun = new SoDirectionalLight;
- space->addChild(sun);
- sun->direction.setValue(-1.0, 0.0, 0.0);
- sun->color.setValue(1.0, 1.0, 0.75);
- sun->intensity = 1.0;
-
- // make translation to position camera
- space->addChild(position = new SoTranslation);
- position->translation.setValue(0.0, 0.0, 0.0);
-
- // make separator for all ships
- space->addChild(ships = new SoSeparator);
-
- // make team bases
- space->addChild(makeTeamBase(RedTeam));
- space->addChild(makeTeamBase(GreenTeam));
- space->addChild(makeTeamBase(BlueTeam));
- space->addChild(makeTeamBase(PurpleTeam));
- makeBaseRadar();
-
- // make asteroids
- space->addChild(makeAsteroids());
-
- // make flags (which are cubes, naturally)
- SoGroup* flagBasic = new SoGroup;
- flagBasic->ref();
- SoComplexity* flagCmplx = new SoComplexity;
- flagBasic->addChild(flagCmplx);
- flagCmplx->value = 0.0;
- flagBasic->addChild(flagRot = new SoRotation);
- SoCube* flagGeom = new SoCube;
- flagBasic->addChild(flagGeom);
- flagGeom->width = FLAGSIZE;
- flagGeom->height = FLAGSIZE;
- flagGeom->depth = FLAGSIZE;
-
- space->addChild(makeTeamFlag(RedTeam, flagBasic));
- space->addChild(makeTeamFlag(GreenTeam, flagBasic));
- space->addChild(makeTeamFlag(BlueTeam, flagBasic));
- space->addChild(makeTeamFlag(PurpleTeam, flagBasic));
-
- return universe;
- }
-
- void deleteUniverse()
- {
- for (int i = 0; i < NUMTEAMS; i++)
- flagGeom[i]->unref();
- universe->unref();
- delete[] asteroidMass;
- }
-
- void universeAdvance(float /*dt*/)
- {
- // spin flags FIXME -- make depend on dt
- flagRot->rotation.setValue(flagSpin * flagRot->rotation.getValue());
-
- }
-
- Team insideBase(float p[3], float r)
- {
- float dx, dy, dz;
- for (int i = 0; i < NUMTEAMS; i++) {
- dx = p[0] - teamBasePos[i][0];
- dy = p[1] - teamBasePos[i][1];
- dz = p[2] - teamBasePos[i][2];
- if (dx*dx + dy*dy + dz*dz < BASERADIUS*BASERADIUS + r*r) return Team(i);
- }
- return NoTeam;
- }
-
- float* basePosition(Team t)
- {
- return teamBasePos[int(t)];
- }
-
- void drawRadarBase(Team)
- {
- bgnclosedline();
- for (int j = 0; j < RADARSIDES; j++)
- v2f(baseRadar[j]);
- endclosedline();
- }
-
- int numberAsteroids()
- {
- return numAsteroids;
- }
-
- float* asteroidPosition(int n)
- {
- return asteroidPos[n];
- }
-
- float asteroidRadius(int n)
- {
- return asteroidRad[n];
- }
-
- void asteroidVisibility(int num, long child)
- {
- if (child == -1)
- asteroidSwitch[num]->whichChild = SO_SWITCH_NONE;
- else
- asteroidSwitch[num]->whichChild = child;
- }
-
- int hitAsteroid(float p[3], float r)
- {
- float dx, dy, dz;
- for (int i = 0; i < numAsteroids; i++) {
- float ar = r + asteroidRad[i];
- dx = p[0] - asteroidPos[i][0];
- if (fabs(dx) > ar) continue;
- dy = p[1] - asteroidPos[i][1];
- if (fabs(dy) > ar) continue;
- dz = p[2] - asteroidPos[i][2];
- if (dx*dx + dy*dy + dz*dz <= ar * ar)
- return i;
- }
- return -1;
- }
-
- void gravityAcceleration(float p[3], float a[3])
- {
- a[0] = a[1] = a[2] = 0.0;
- float d, dx, dy, dz;
- for (int i = 0; i < numAsteroids; i++) {
- dx = p[0] - asteroidPos[i][0];
- dy = p[1] - asteroidPos[i][1];
- dz = p[2] - asteroidPos[i][2];
- d = sqrt(dx * dx + dy * dy + dz * dz);
- if (d < asteroidRad[i]) continue; // inside so ignore
- d = 1.0 / d;
- a[0] += asteroidMass[i] * dx * d;
- a[1] += asteroidMass[i] * dy * d;
- a[2] += asteroidMass[i] * dz * d;
- }
- }
-
- void drawRadarAsteroid(int num)
- {
- bgnclosedline();
- for (int j = 0; j < RADARSIDES; j++)
- v2f(asteroidRadar[num][j]);
- endclosedline();
- }
-
- SoSeparator* flagGeometry(Team t)
- {
- return flagGeom[int(t)];
- }
-
- void flagInSpace(Team t, int e)
- {
- if (e) flagState[int(t)] |= InSpace;
- else flagState[int(t)] &= ~InSpace;
- TeamInfo& ti = getTeam(t);
- flagPos[int(t)]->translation.setValue(ti.position);
- flags[int(t)]->whichChild = (flagState[int(t)] == SwitchedOn) ?
- SO_SWITCH_ALL : SO_SWITCH_NONE;
- }
-
- void flagVisibility(Team t, int visible)
- {
- if (visible) flagState[int(t)] |= Visible;
- else flagState[int(t)] &= ~Visible;
- flags[int(t)]->whichChild = (flagState[int(t)] == SwitchedOn) ?
- SO_SWITCH_ALL : SO_SWITCH_NONE;
- }
-